package com.gitee.sparta.core.cluster.strategy;

import com.gitee.sparta.core.bean.cluster.ClusterCmd;
import com.gitee.sparta.common.helpers.JsonHelper;
import com.gitee.sparta.core.bean.cluster.ClusterProtocol;
import com.gitee.sparta.core.cluster.AbstractClusterFollower;
import com.gitee.sparta.core.cluster.ClusterCache;
import com.gitee.sparta.core.property.ClusterProperties;
import com.gitee.sparta.core.property.SpartaCoreProperties;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.channels.SocketChannel;
import java.util.concurrent.TimeUnit;

/**
 * follower 节点心跳数据
 * <p>
 *
 * @author zyred
 * @since v 1.0.0
 */
@Slf4j
public class FollowerNioHeartbeatStrategy extends Thread {

    private final SpartaCoreProperties properties;
    private final SocketChannel socketChannel;
    private final ClusterProtocol protocol;

    public FollowerNioHeartbeatStrategy(SpartaCoreProperties properties, SocketChannel socketChannel, int myId) {
        this.properties = properties;
        this.socketChannel = socketChannel;
        this.protocol = new ClusterProtocol(ClusterCmd.HEARTBEAT, myId, ClusterCache.getLeaderSid());
        this.setName("heartbeat-thread");
        this.start();
        log.info("[Sparta] myId : {}", myId);
    }

    @Override
    public void run() {
        ClusterProperties cluster = this.properties.getCluster();
        long freq = cluster.getClusterHeartbeatFreq().getSeconds();
        while (!Thread.interrupted()) {
            try {
                // if (log.isDebugEnabled()) {
                    log.info("[Sparta] heartbeat : {}，  socket : {}", JsonHelper.getJsonString(protocol), socketChannel.getRemoteAddress());
                //}
                AbstractClusterFollower.sendQueue(protocol);
                TimeUnit.SECONDS.sleep(freq);
            } catch (Exception ex) {
                try {
                    socketChannel.close();
                    Thread.currentThread().interrupt();
                    return;
                } catch (IOException e) {
                    log.error("[Sparta] heartbeat error, exception : {}", ex.getMessage(), ex);
                }
            }
        }
        log.info("[Sparta] follower heartbeat stop ...");
    }
}
